#pragma semicolon 1
#pragma newdecls required

#include <sourcemod>
#include <left4dhooks>


#define PLUGIN_VERSION "1.0"


public Plugin myinfo =
{
	name = "l4d2_advanced_shove_detection",
	author = "豆瓣酱な",
	description = "生还者右键击飞队友.",
	version = PLUGIN_VERSION,
	url = "https://gitee.com/sweet-and-sour-bombs/adfvsdsd"
};

// 定义ConVar变量
ConVar c_shove;
ConVar c_shovez;


public void OnPluginStart()
{
	// 注册ConVar变量
	c_shove = CreateConVar("sm_c_shove", "150.0", "水平击飞力度", FCVAR_NOTIFY, true, 100.0, true, 2000.0);
    
	c_shovez = CreateConVar("sm_c_shovez", "251.0", "垂直击飞力度", FCVAR_NOTIFY, true, 100.0, true, 2000.0);
    


	// 自动生成配置文件
	//AutoExecConfig(true, "l4d2_advanced_shove_detection");
    

}

public void L4D2_OnEntityShoved_Post(int client, int entity, int weapon, const float vecDir[3], bool bIsHighPounce)
{

	if (!IsValidClient(client))
	return;
	
	if (IsClientPinned(entity) || IsPlayerIncapacitated(entity) || IsPlayerHanging(entity))
	{
		return;
	}	
	
	
	/* ---- 动态获取ConVar参数 ---- */
	float g_shove = c_shove.FloatValue;
	float g_shovez = c_shovez.FloatValue;    

	int attackerTeam = GetClientTeam(client);
    

	if (entity > 0 && entity <= MaxClients)
	{
		if (IsValidClient(entity))
		{
			int victimTeam = GetClientTeam(entity);
            

			if (attackerTeam == 2 && victimTeam == 2)
			{
				PrintToChatAll("\x04[提示] 生还者 \x03%N \x04推飞队友 \x03%N", client, entity);
				/* ---- 物理计算 ---- */
				float HeadingVector[3], resulting[3], fPos[3];
    
				// 获取攻击者视角方向
				GetClientEyeAngles(client, HeadingVector);
    
				// 获取当前速度
				GetEntPropVector(entity, Prop_Data, "m_vecVelocity", resulting);
    
				// 计算方向分量
				resulting[0] += Cosine(DegToRad(HeadingVector[1])) * g_shove;
				resulting[1] += Sine(DegToRad(HeadingVector[1])) * g_shove;
				resulting[2] = g_shovez;
    
				// 应用效果
				TeleportEntity(entity, NULL_VECTOR, NULL_VECTOR, resulting);
				GetClientAbsOrigin(client, fPos);
				L4D_StaggerPlayer(entity, client, fPos);
				L4D2_CTerrorPlayer_Fling(entity, client, resulting);					
			}

		}
	}
}

bool IsValidClient(int client)
{
	return (client > 0 && client <= MaxClients && IsClientInGame(client));
}

//判断玩家是否被控
bool IsClientPinned(int client)
{
	// 检查玩家有效性
	if(!IsValidClient(client))
		return false;

	if (GetEntPropEnt(client, Prop_Send, "m_pummelAttacker") > 0)
		return true;
	if (GetEntPropEnt(client, Prop_Send, "m_carryAttacker") > 0)
		return true;
	if (GetEntPropEnt(client, Prop_Send, "m_pounceAttacker") > 0)
		return true;
	if (GetEntPropEnt(client, Prop_Send, "m_jockeyAttacker") > 0)
		return true;
	if (GetEntPropEnt(client, Prop_Send, "m_tongueOwner") > 0)
		return true;
	return false;
}

// 判断玩家是否倒地
bool IsPlayerIncapacitated(int client)
{
	// 检查玩家有效性
	if(!IsValidClient(client))
		return false;
    
	// 使用Prop_Send获取倒地状态
	return GetEntProp(client, Prop_Send, "m_isIncapacitated") != 0;
}

// 判断玩家是否挂边
bool IsPlayerHanging(int client)
{
	// 检查玩家有效性
	if(!IsValidClient(client))
	return false;
    
	// 使用Prop_Send获取挂边状态
	return GetEntProp(client, Prop_Send, "m_isHangingFromLedge") != 0;
}
